from fastapi import APIRouter, HTTPException, Depends
from fastapi.security import OAuth2PasswordBearer
from pydantic import BaseModel, EmailStr
from typing import Optional
import jwt
from datetime import datetime, timedelta
from passlib.context import CryptContext

router = APIRouter()

# 密码加密工具
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")

# JWT配置
SECRET_KEY = "your-secret-key"  # 在生产环境中应该使用环境变量
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30

# 请求模型
class UserRegister(BaseModel):
    username: str
    full_name: str
    email: Optional[str] = None
    phone: Optional[str] = None
    password: str

class UserLogin(BaseModel):
    username: str  # 用户名/邮箱/手机号
    password: str

# 响应模型
class UserResponse(BaseModel):
    id: int
    username: str
    full_name: str
    email: Optional[str]
    phone: Optional[str]
    created_at: datetime
    is_active: bool
    is_admin: bool = False

class LoginResponse(BaseModel):
    success: bool
    message: str
    access_token: Optional[str] = None
    token_type: Optional[str] = None
    user: Optional[UserResponse] = None

class RegisterResponse(BaseModel):
    success: bool
    message: str
    user: Optional[UserResponse] = None

# 用户数据库模拟（实际应用中应该使用真实数据库）
fake_users_db = {}
user_id_counter = 1

# 创建访问令牌
def create_access_token(data: dict):
    to_encode = data.copy()
    expire = datetime.utcnow() + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
    to_encode.update({"exp": expire})
    encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
    return encoded_jwt

# 验证密码
def verify_password(plain_password, hashed_password):
    return pwd_context.verify(plain_password, hashed_password)

# 获取密码哈希
def get_password_hash(password):
    return pwd_context.hash(password)

# 根据用户名/邮箱/手机号获取用户
def get_user(identifier: str):
    # 检查是否为邮箱登录
    email_user = next((user for user in fake_users_db.values() 
                      if user.get("email") == identifier), None)
    if email_user:
        return email_user

    # 检查是否为手机号登录
    phone_user = next((user for user in fake_users_db.values() 
                      if user.get("phone") == identifier), None)
    if phone_user:
        return phone_user

    # 最后检查用户名
    return fake_users_db.get(identifier)

@router.post("/admin/users/", response_model=RegisterResponse)
async def create_user(user: UserRegister):
    """
    创建新用户
    """
    global user_id_counter

    # 检查用户名是否已存在
    if user.username in fake_users_db:
        return {
            "success": False,
            "message": "用户名已被注册",
            "error_code": "USERNAME_EXISTS"
        }

    # 检查邮箱是否已被使用
    if user.email and any(u.get("email") == user.email for u in fake_users_db.values()):
        return {
            "success": False,
            "message": "邮箱已被注册",
            "error_code": "EMAIL_EXISTS"
        }
    
    # 检查手机号是否已被使用
    if user.phone and any(u.get("phone") == user.phone for u in fake_users_db.values()):
        return {
            "success": False,
            "message": "手机号已被注册",
            "error_code": "PHONE_EXISTS"
        }
    
    # 创建新用户
    hashed_password = get_password_hash(user.password)
    user_dict = {
        "id": user_id_counter,
        "username": user.username,
        "full_name": user.full_name,
        "email": user.email,
        "phone": user.phone,
        "hashed_password": hashed_password,
        "created_at": datetime.utcnow(),
        "is_active": True,
        "is_admin": False
    }
    
    fake_users_db[user.username] = user_dict
    user_id_counter += 1
    
    return {
        "success": True,
        "message": "注册成功",
        "user": user_dict
    }

@router.post("/auth/login", response_model=LoginResponse)
async def login(user_data: UserLogin):
    """
    用户登录
    - 支持使用用户名、邮箱或手机号登录
    """
    user = get_user(user_data.username)
    
    if user is None:
        return {
            "success": False,
            "message": "用户不存在",
            "error_code": "USER_NOT_FOUND"
        }
    
    if not user["is_active"]:
        return {
            "success": False,
            "message": "账号已被禁用",
            "error_code": "ACCOUNT_DISABLED"
        }
    
    if not verify_password(user_data.password, user["hashed_password"]):
        return {
            "success": False,
            "message": "密码错误",
            "error_code": "INVALID_PASSWORD"
        }
    
    # 创建访问令牌
    access_token = create_access_token(
        data={"sub": user["username"]}
    )
    
    return {
        "success": True,
        "message": "登录成功",
        "access_token": access_token,
        "token_type": "bearer",
        "user": user
    }

@router.post("/admin/refresh")
async def refresh_token(current_token: str = Depends(OAuth2PasswordBearer(tokenUrl="admin/login"))):
    """
    刷新访问令牌
    """
    try:
        payload = jwt.decode(current_token, SECRET_KEY, algorithms=[ALGORITHM])
        username = payload.get("sub")
        if username is None:
            raise HTTPException(
                status_code=401,
                detail="无效的认证凭据"
            )
        
        # 创建新的访问令牌
        access_token = create_access_token(
            data={"sub": username}
        )
        
        return {
            "access_token": access_token,
            "token_type": "bearer"
        }
    except jwt.JWTError:
        raise HTTPException(
            status_code=401,
            detail="无效的认证凭据"
        ) 